#include "setting.h"
#include "base.h"
#include "text.h"
#include "sound.h"

#include <fstream>
#include <sstream>
#include <SdkTrays.h>

#define RENDERER_NAME "Direct3D9 Rendering Subsystem"

bool write_pair(std::ofstream& f, Ogre::String key, Ogre::String value)
{
	f << key << "=" << value << std::endl;
	return !f.fail();
}

bool write_to_cfg(const Ogre::ConfigOptionMap& a, float mus, float fx, Ogre::String cam, bool* dir_created)
{
	std::ofstream f(CONFIG_FILE_NAME);

	if (!f.is_open())
	{
		CreateDirectory(USERDATA_DIR, 0);
		f.open(CONFIG_FILE_NAME);
		if (!f.is_open())
		{
			f.close();
			return false;
		}
		else
		{
			if (dir_created)
				*dir_created = true;
		}
	}

	if (!write_pair(f, CFG_KEY_RENDERER, RENDERER_NAME))
	{
		f.close();
		return false;
	}

	if (!write_pair(f, CFG_KEY_MUSIC_VOL, std::to_string((long long)(100 * mus))))
	{
		f.close();
		return false;
	}
	
	if (!write_pair(f, CFG_KEY_FX_VOL, std::to_string((long long)(100 * fx))))
	{
		f.close();
		return false;
	}

	if (!write_pair(f, CFG_KEY_CAM, cam))
	{
		f.close();
		return false;
	}

	if (!(f<<"\n["<<RENDERER_NAME<<"]\n"))
	{
		f.close();
		return false;
	}

	for (Ogre::ConfigOptionMap::const_iterator it = a.begin(); it != a.end(); ++it)
	{
		std::string s;
		// Make the program windowize as default
		//if (it->first == CFG_KEY_FULLSCREEN)
		//	s = "No";
		//else
			s = it->second.currentValue;

		if (!write_pair(f, it->first, s))
		{
			f.close();
			return false;
		}
	}
	f.close();
	return true;
}

bool Base::load_cfg()
{
	
	const Ogre::RenderSystemList& rsl = root->getAvailableRenderers();
	Ogre::ConfigOptionMap* cm_default;

	for (Ogre::RenderSystemList::const_iterator it = rsl.begin(); it != rsl.end(); ++it)
	{
		//MessageBox(NULL, (*it)->getName().c_str(), "rsl", MB_OK);
		if ((*it)->getName() == RENDERER_NAME)
		{
			cm_default = new Ogre::ConfigOptionMap(
				(*it)->getConfigOptions()
				);
			break;
		}
	}

	if (root->restoreConfig())
	{
		const Ogre::ConfigOptionMap& cm = root->getRenderSystem()->getConfigOptions();
		bool ok_flag = true;
		for (Ogre::ConfigOptionMap::const_iterator i = cm.begin(); i != cm.end(); ++i)
			if (std::find(i->second.possibleValues.begin(),
						  i->second.possibleValues.end(),
						  i->second.currentValue)
				== i->second.possibleValues.end())
			{
				ok_flag = false;
				break;
			}
		if (ok_flag)
		{
			Ogre::ConfigFile cf;
			cf.load(CONFIG_FILE_NAME);
			if (cf.getSetting(CFG_KEY_MUSIC_VOL) != "")
			{
				std::istringstream f(cf.getSetting(CFG_KEY_MUSIC_VOL));
				int a = -1;
				f >> a;
				if (a == -1)
					throw Ogre::Exception(4, "bad vol key", "setting.cpp. Base::load_cfg");
				sounder.set_music_vol(a * .01f);
			}
		
			if (cf.getSetting(CFG_KEY_FX_VOL) != "")
			{
				std::istringstream f(cf.getSetting(CFG_KEY_FX_VOL));
				int a = -1;
				f >> a;
				if (a == -1)
					throw Ogre::Exception(4, "bad vol key", "setting.cpp. Base::load_cfg");
				sounder.set_fx_vol(a * .01f);
			}

			if (cf.getSetting(CFG_KEY_CAM) != "")
			{
				cam_selected = cf.getSetting(CFG_KEY_CAM);
			}
			delete cm_default;
			return true;
		}
	}
	
	// the CFG file is not correct, recreate one.
	first_run = true;
	
	for (Ogre::RenderSystemList::const_iterator it = rsl.begin(); it != rsl.end(); ++it)
	{
		//MessageBox(NULL, (*it)->getName().c_str(), "rsl", MB_OK);
		if ((*it)->getName() == RENDERER_NAME)
		{
			cm_default->find(CFG_KEY_FULLSCREEN)->second.currentValue = "No";
			if (!write_to_cfg(*cm_default))
				throw Ogre::Exception(3, get_text("ERROR_STCFG"), "setting.cpp, write_to_cfg");
			if (root->restoreConfig())
			{
				return true;
				delete cm_default;
			}
			else
			{
				DeleteFile(CONFIG_FILE_NAME);
				break;
			}
		}
	}
	
	delete cm_default;
	throw Ogre::Exception(3, get_text("ERROR_RS"), "setting.cpp, Base::load_cfg");
}



bool Base::reinit()
{
	OgreBites::SelectMenu* sm;
	Ogre::RenderSystem* rs = root->getRenderSystem();

	sm = (OgreBites::SelectMenu*) tray_manager->getWidget("fullscreen_select");
	
	if (sm != NULL)
	{
		rs->setConfigOption(CFG_KEY_FULLSCREEN, sm->getSelectedItem());
	}

	sm = (OgreBites::SelectMenu*) tray_manager->getWidget("video_select");

	if (sm != NULL)
	{
		rs->setConfigOption(CFG_KEY_VIDEO, sm->getSelectedItem());
	}

	sm = (OgreBites::SelectMenu*) tray_manager->getWidget("FSAA_select");

	if (sm != NULL)
	{
		rs->setConfigOption(CFG_KEY_FSAA, sm->getSelectedItem());
	}

	sm = (OgreBites::SelectMenu*) tray_manager->getWidget("device_select");

	if (sm != NULL)
	{
		rs->setConfigOption(CFG_KEY_DEVICE, sm->getSelectedItem());
	}
	cam_selected = ((OgreBites::SelectMenu*) tray_manager->getWidget("cam_select"))
		->getSelectedItem();

	OgreBites::Slider* sl;

	sl = (OgreBites::Slider*) tray_manager->getWidget("music_select");

	if (sl != NULL)
	{
		sounder.set_music_vol(sl->getValue() * 0.01f);
	}

	sl = (OgreBites::Slider*) tray_manager->getWidget("fx_select");
	
	if (sl != NULL)
	{
		sounder.set_fx_vol(sl->getValue() * 0.01f);
	}

	CopyFile(CONFIG_FILE_NAME, CONFIG_BAKFILE_NAME, false);
	write_to_cfg(rs->getConfigOptions(),
				 sounder.get_music_vol(),
				 sounder.get_fx_vol(),
				 cam_selected);

	flag = BASE_RESET;
	return true;
}

char* Base::get_restart_param()
{
	if (flag != BASE_RESET)
		return NULL;
	
	if (last_flag == BASE_SELECT)
		return PARAM_SAVE;

	if (last_flag == BASE_START)
		return PARAM_STARTANDSAVE;

	if (last_flag == BASE_HELP)
		return PARAM_HELP;
	throw Ogre::Exception(5, "bad restart situation", "setting.cpp, Base::get_restart_param");
}


void Base::work_exec_param(Ogre::String params)
{
	if (params == PARAM_SAVE)
	{
		last_flag = BASE_RESET;
		flag = BASE_OPEN;
	}
	else if (params == PARAM_STARTANDSAVE)
	{
		last_flag = BASE_RESET;
		flag = BASE_START;
	}
	else if (params == PARAM_HELP)
	{
		last_flag = BASE_RESET;
		flag = BASE_HELP;
	}
	else // default
	{
		flag = BASE_OPEN;
	}
}
